import matplotlib.pyplot as plt
import matplotlib.animation as animation

# 初始化汉诺塔状态
def init_hanoi(n):
    return [list(range(n, 0, -1)), [], []]

# 绘制汉诺塔
def draw_hanoi(state, ax):
    ax.clear()
    ax.set_xlim(-1, 7)  # 扩大柱子间的间隔
    ax.set_ylim(0, len(state[0]) + 2)  # 固定高度
    ax.set_facecolor('#f0f0f0')  # 设置背景颜色
    ax.axis('off')  # 隐藏坐标轴
    colors = ['#FF5733', '#33FF57', '#3357FF', '#F4D03F', '#8E44AD', '#1ABC9C', '#E74C3C', '#2ECC71']
    tower_width = 0.15  # 固定柱子的宽度
    disk_height = 0.5  # 固定盘子的高度

    # 绘制柱子
    for i, x in enumerate([1, 3, 5]):  # 调整柱子的位置
        ax.bar(x, len(state[0]) + 1, bottom=0, width=tower_width, color='black', align='center')

    # 绘制盘子
    for i, tower in enumerate(state):
        x = [1, 3, 5][i]  # 根据柱子的位置绘制盘子
        for j, disk in enumerate(tower):
            disk_width = 0.5 + disk * 0.3  # 根据盘子的大小调整宽度
            ax.bar(x, disk_height, bottom=j * disk_height, width=disk_width, align='center', color=colors[disk % len(colors)], edgecolor='black')

# 汉诺塔递归逻辑
def hanoi(n, source, target, auxiliary, moves):
    if n == 1:
        moves.append((source, target))
    else:
        hanoi(n - 1, source, auxiliary, target, moves)
        moves.append((source, target))
        hanoi(n - 1, auxiliary, target, source, moves)

# 动画更新函数
def update(frame, state, moves, ax):
    source, target = moves[frame]
    state[target].append(state[source].pop())
    draw_hanoi(state, ax)

# 主函数
def main():
    n = 8  # 盘子数量
    state = init_hanoi(n)
    moves = []
    hanoi(n, 0, 2, 1, moves)

    # 创建动画
    fig, ax = plt.subplots(figsize=(8, 6))  # 调整画布大小
    ani = animation.FuncAnimation(fig, update, frames=len(moves), fargs=(state, moves, ax), interval=500, repeat=False)
    plt.show()

if __name__ == "__main__":
    main()